package Server.netty.handler;

import Server.provider.ServiceProvider;
import Server.server.ratelimit.RateLimit;
import common.Message.RpcRequest;
import common.Message.RpcResponse;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.AllArgsConstructor;

import java.lang.reflect.Method;

@AllArgsConstructor
public class NettyRPCServerHandler extends SimpleChannelInboundHandler<RpcRequest> {

    private ServiceProvider serviceProvider;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcRequest msg) throws Exception {
        // 接受Request，读取并调用服务
        RpcResponse rpcResponse = getRpcResponse(msg);
        ctx.writeAndFlush(rpcResponse);
        ctx.close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    private RpcResponse getRpcResponse(RpcRequest rpcRequest) {
        // 根据请求得到服务名
        String interfaceName = rpcRequest.getInterfaceName();
        // 接口限流降级
        RateLimit rateLimit = serviceProvider.getRateLimitProvider().getRateLimit(interfaceName);
        if (!rateLimit.getToken()) {
            // 如果获取令牌失败，进行限流降级，返回失败响应
            System.out.println("限流降级");
            return RpcResponse.fail();
        }
        // 根据服务名获取服务对象类
        Object serviceClass = serviceProvider.getService(interfaceName);
        try {
            // 根据反射调用服务方法
            Method method = serviceClass.getClass().getMethod(rpcRequest.getMethodName(), rpcRequest.getParamTypes());
            Object invoke = method.invoke(serviceClass, rpcRequest.getParams());
            return RpcResponse.success(invoke);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("调用方法出错");
            return RpcResponse.fail();
        }
    }
}
